-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[RISCV] Refactor DAG-to-DAG Selection: Port lowering code for qc.insb/qc.insbi to RISCVISelLowering.cpp
#157618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Change-Id: Idb479a3cd61d2c0cbd9c212ae8c09c94270687ca
Change-Id: I8c661ef7a70fdd45b592c7b5e9c843318b0d2fe6
|
@llvm/pr-subscribers-backend-risc-v Author: quic_hchandel (hchandel) ChangesFull diff: https://github.com/llvm/llvm-project/pull/157618.diff 3 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 142414ddf7132..07d8ef2c1fd22 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -205,7 +205,7 @@ static SDValue selectImmSeq(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
return SrcReg;
}
-static SDValue selectImm(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
+SDValue selectImm(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
int64_t Imm, const RISCVSubtarget &Subtarget) {
RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Imm, Subtarget);
@@ -677,94 +677,6 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
return false;
}
-bool RISCVDAGToDAGISel::trySignedBitfieldInsertInMask(SDNode *Node) {
- // Supported only in Xqcibm for now.
- if (!Subtarget->hasVendorXqcibm())
- return false;
-
- using namespace SDPatternMatch;
-
- SDValue X;
- APInt MaskImm;
- if (!sd_match(Node, m_Or(m_OneUse(m_Value(X)), m_ConstInt(MaskImm))))
- return false;
-
- unsigned ShAmt, Width;
- if (!MaskImm.isShiftedMask(ShAmt, Width) || MaskImm.isSignedIntN(12))
- return false;
-
- // If Zbs is enabled and it is a single bit set we can use BSETI which
- // can be compressed to C_BSETI when Xqcibm in enabled.
- if (Width == 1 && Subtarget->hasStdExtZbs())
- return false;
-
- // If C1 is a shifted mask (but can't be formed as an ORI),
- // use a bitfield insert of -1.
- // Transform (or x, C1)
- // -> (qc.insbi x, -1, width, shift)
- SDLoc DL(Node);
- MVT VT = Node->getSimpleValueType(0);
-
- SDValue Ops[] = {X, CurDAG->getSignedTargetConstant(-1, DL, VT),
- CurDAG->getTargetConstant(Width, DL, VT),
- CurDAG->getTargetConstant(ShAmt, DL, VT)};
- SDNode *BitIns = CurDAG->getMachineNode(RISCV::QC_INSBI, DL, VT, Ops);
- ReplaceNode(Node, BitIns);
- return true;
-}
-
-// Generate a QC_INSB/QC_INSBI from 'or (and X, MaskImm), OrImm' iff the value
-// being inserted only sets known zero bits.
-bool RISCVDAGToDAGISel::tryBitfieldInsertOpFromOrAndImm(SDNode *Node) {
- // Supported only in Xqcibm for now.
- if (!Subtarget->hasVendorXqcibm())
- return false;
-
- using namespace SDPatternMatch;
-
- SDValue And;
- APInt MaskImm, OrImm;
- if (!sd_match(Node, m_Or(m_OneUse(m_And(m_Value(And), m_ConstInt(MaskImm))),
- m_ConstInt(OrImm))))
- return false;
-
- // Compute the Known Zero for the AND as this allows us to catch more general
- // cases than just looking for AND with imm.
- KnownBits Known = CurDAG->computeKnownBits(Node->getOperand(0));
-
- // The bits being inserted must only set those bits that are known to be zero.
- if (!OrImm.isSubsetOf(Known.Zero)) {
- // FIXME: It's okay if the OrImm sets NotKnownZero bits to 1, but we don't
- // currently handle this case.
- return false;
- }
-
- unsigned ShAmt, Width;
- // The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00).
- if (!Known.Zero.isShiftedMask(ShAmt, Width))
- return false;
-
- // QC_INSB(I) dst, src, #width, #shamt.
- SDLoc DL(Node);
- MVT VT = Node->getSimpleValueType(0);
- SDValue ImmNode;
- auto Opc = RISCV::QC_INSB;
-
- int32_t LIImm = OrImm.getSExtValue() >> ShAmt;
-
- if (isInt<5>(LIImm)) {
- Opc = RISCV::QC_INSBI;
- ImmNode = CurDAG->getSignedTargetConstant(LIImm, DL, MVT::i32);
- } else {
- ImmNode = selectImm(CurDAG, DL, MVT::i32, LIImm, *Subtarget);
- }
-
- SDValue Ops[] = {And, ImmNode, CurDAG->getTargetConstant(Width, DL, VT),
- CurDAG->getTargetConstant(ShAmt, DL, VT)};
- SDNode *BitIns = CurDAG->getMachineNode(Opc, DL, VT, Ops);
- ReplaceNode(Node, BitIns);
- return true;
-}
bool RISCVDAGToDAGISel::trySignedBitfieldInsertInSign(SDNode *Node) {
// Only supported with XAndesPerf at the moment.
@@ -1384,12 +1296,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
return;
}
case ISD::OR: {
- if (trySignedBitfieldInsertInMask(Node))
- return;
-
- if (tryBitfieldInsertOpFromOrAndImm(Node))
- return;
-
if (tryShrinkShlLogicImm(Node))
return;
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index ba129457d6284..2abc6991d34e2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -16,10 +16,14 @@
#include "RISCV.h"
#include "RISCVTargetMachine.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Support/KnownBits.h"
// RISC-V specific code to select RISC-V machine instructions for
// SelectionDAG operations.
+
+llvm::SDValue selectImm(llvm::SelectionDAG *CurDAG, const llvm::SDLoc &DL, const llvm::MVT VT,
+ int64_t Imm, const llvm::RISCVSubtarget &Subtarget);
namespace llvm {
class RISCVDAGToDAGISel : public SelectionDAGISel {
const RISCVSubtarget *Subtarget = nullptr;
@@ -74,8 +78,6 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
bool tryShrinkShlLogicImm(SDNode *Node);
bool trySignedBitfieldExtract(SDNode *Node);
bool trySignedBitfieldInsertInSign(SDNode *Node);
- bool trySignedBitfieldInsertInMask(SDNode *Node);
- bool tryBitfieldInsertOpFromOrAndImm(SDNode *Node);
bool tryUnsignedBitfieldExtract(SDNode *Node, const SDLoc &DL, MVT VT,
SDValue X, unsigned Msb, unsigned Lsb);
bool tryUnsignedBitfieldInsertInZero(SDNode *Node, const SDLoc &DL, MVT VT,
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 44434ff51288f..0098938031f1d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RISCVISelLowering.h"
+#include "RISCVISelDAGToDAG.h"
#include "MCTargetDesc/RISCVMatInt.h"
#include "RISCV.h"
#include "RISCVConstantPoolValue.h"
@@ -16192,7 +16193,6 @@ static SDValue combineXorToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
return SDValue();
using namespace SDPatternMatch;
-
SDValue Base, Inserted;
APInt CMask;
if (!sd_match(N, m_Xor(m_Value(Base),
@@ -16203,7 +16203,6 @@ static SDValue combineXorToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
if (N->getValueType(0) != MVT::i32)
return SDValue();
-
unsigned Width, ShAmt;
if (!CMask.isShiftedMask(ShAmt, Width))
return SDValue();
@@ -16224,10 +16223,101 @@ static SDValue combineXorToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(RISCVISD::QC_INSB, DL, MVT::i32, Ops);
}
+static SDValue combineOrToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
+ const RISCVSubtarget &Subtarget) {
+ if (!Subtarget.hasVendorXqcibm())
+ return SDValue();
+
+ using namespace SDPatternMatch;
+
+ SDValue X;
+ APInt MaskImm;
+ if (!sd_match(N, m_Or(m_OneUse(m_Value(X)), m_ConstInt(MaskImm))))
+ return SDValue();
+
+ unsigned ShAmt, Width;
+ if (!MaskImm.isShiftedMask(ShAmt, Width) || MaskImm.isSignedIntN(12))
+ return SDValue();
+
+ if (N->getValueType(0) != MVT::i32)
+ return SDValue();
+
+ // If Zbs is enabled and it is a single bit set we can use BSETI which
+ // can be compressed to C_BSETI when Xqcibm in enabled.
+ if (Width == 1 && Subtarget.hasStdExtZbs())
+ return SDValue();
+
+ // If C1 is a shifted mask (but can't be formed as an ORI),
+ // use a bitfield insert of -1.
+ // Transform (or x, C1)
+ // -> (qc.insbi x, -1, width, shift)
+ SDLoc DL(N);
+
+ SDValue Ops[] = {X, DAG.getSignedConstant(-1, DL, MVT::i32),
+ DAG.getConstant(Width, DL, MVT::i32),
+ DAG.getConstant(ShAmt, DL, MVT::i32)};
+ return DAG.getNode(RISCVISD::QC_INSB, DL, MVT::i32, Ops);
+}
+
+// Generate a QC_INSB/QC_INSBI from 'or (and X, MaskImm), OrImm' iff the value
+// being inserted only sets known zero bits.
+static SDValue combineOrAndToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
+ const RISCVSubtarget &Subtarget) {
+ // Supported only in Xqcibm for now.
+ if (!Subtarget.hasVendorXqcibm())
+ return SDValue();
+
+ using namespace SDPatternMatch;
+
+ SDValue And;
+ APInt MaskImm, OrImm;
+ if (!sd_match(N, m_Or(m_OneUse(m_And(m_Value(And), m_ConstInt(MaskImm))),
+ m_ConstInt(OrImm))))
+ return SDValue();
+
+ // Compute the Known Zero for the AND as this allows us to catch more general
+ // cases than just looking for AND with imm.
+ KnownBits Known = DAG.computeKnownBits(N->getOperand(0));
+
+ // The bits being inserted must only set those bits that are known to be
+ // zero.
+ if (!OrImm.isSubsetOf(Known.Zero)) {
+ // FIXME: It's okay if the OrImm sets NotKnownZero bits to 1, but we don't
+ // currently handle this case.
+ return SDValue();
+ }
+
+ unsigned ShAmt, Width;
+ // The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00).
+ if (!Known.Zero.isShiftedMask(ShAmt, Width))
+ return SDValue();
+
+ if (N->getValueType(0) != MVT::i32)
+ return SDValue();
+
+ // QC_INSB(I) dst, src, #width, #shamt.
+ SDLoc DL(N);
+ SDValue ImmNode;
+
+ int32_t LIImm = OrImm.getSExtValue() >> ShAmt;
+ ImmNode = DAG.getSignedConstant(LIImm, DL, MVT::i32);
+
+ if (!isInt<5>(LIImm)) {
+ ImmNode = selectImm(&DAG, DL, MVT::i32, LIImm, Subtarget);
+ }
+ SDValue Ops[] = {And, ImmNode, DAG.getConstant(Width, DL, MVT::i32),
+ DAG.getConstant(ShAmt, DL, MVT::i32)};
+ return DAG.getNode(RISCVISD::QC_INSB, DL, MVT::i32, Ops);
+}
+
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
const RISCVSubtarget &Subtarget) {
SelectionDAG &DAG = DCI.DAG;
+ if (SDValue V = combineOrToBitfieldInsert(N, DAG, Subtarget))
+ return V;
+ if (SDValue V = combineOrAndToBitfieldInsert(N, DAG, Subtarget))
+ return V;
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
return V;
if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Change-Id: I7d33ecc31d2cefd65c6e11019ad4b4db4fd968ef
Change-Id: If3ff9fb4bdcfd557426f863b5235d2f10535d00b
Change-Id: I8dba54c5c78c86fab22e03b8d10079241e18d242
lenary
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
|
@topperc do you have any comments? |
topperc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/14100 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/21431 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/168/builds/16313 Here is the relevant piece of the build log for the reference |
This is a follow-up to #154135 and does similar changes for
qc.insb/qc.insbi.